<?php

namespace slinks\extensions\twig;

use slinks\SlinksPaths;
use slinks\common\UniversalClassLoader;
use slinks\core\dependencyInjectionExt\extension\Extension;
use slinks\core\DependencyInjection\ContainerBuilder;
use slinks\core\dependencyInjectionExt\ContainerUtil;
use slinks\core\dependencyInjectionExt\annotation\ServiceDefiningAnnotationUtil;
use slinks\core\dependencyInjectionExt\annotation\ServiceDefiningAnnotationVisitor;
use slinks\common\Finder\Finder;
use slinks\common\io\AnnotationReader;
use slinks\core\Config\Resource\FileResource;
use slinks\core\DependencyInjection\Definition;

/**
 * Twig extension setups the Twig Engine. 
 * 
 * twig:config can be used to set the default options used when starting twig.
 * Addtionally twig:config can set all directories to look for templates in.
 * 
 * @author Navid Mitchell
 *
 */
class TwigExtension extends Extension {
    const TWIG_ENGINE = 'twig.engine';
    const TWIG_TEMPLATE_DIRS = 'twig.template.dirs';
    const TWIG_OPTIONS = 'twig.options';

    public function configLoad(array $configs, ContainerBuilder $container) {

        if (!$container->hasDefinition(self::TWIG_ENGINE)) {
            
            // this gets done here as well as within the Engine so the Twig compiler pass and annotation scan will complete properly.
            $loader = new UniversalClassLoader();
            $loader->registerPrefix('Twig', SlinksPaths::twigDir());
            $loader->register();
            
            // first add needed default parameters
            if(!$container->hasParameter(self::TWIG_TEMPLATE_DIRS)){
                $container->setParameter(self::TWIG_TEMPLATE_DIRS, '%slinks.config.root.dir%/views');
            }
            $container->setParameter(self::TWIG_OPTIONS,array( 'debug'=>'%slinks.debug.enabled%','cache'=>'%slinks.cache.dir%/twig'));
            
            $path = __DIR__ .DIRECTORY_SEPARATOR. 'core';
            
            $container->addResource(new FileResource($path));

            $reader = new AnnotationReader(new ServiceDefiningAnnotationVisitor($container));

            $finder = new Finder();

            $reader->read($finder->files()->name('*.php')->in($path));
             
            $this->addClassesToCompile(array(
                'Twig_Environment',
                'Twig_ExtensionInterface',
                'Twig_Extension',
                'Twig_Extension_Core',
                'Twig_Extension_Escaper',
                'Twig_Extension_Optimizer',
                'Twig_LoaderInterface',
                'Twig_Loader_Filesystem',
                'Twig_Markup',
                'Twig_TemplateInterface',
                'Twig_Template',
            ));
        }  
        // we do not overwrite since the order the configs are called is complex to gurantee.
        // TODO: look at migrating to new Symfony DI config type logic ordering is not an issue.
        if (isset($configs['templateDir'])) {
            ContainerUtil::addValueToArrayParameter($container, self::TWIG_TEMPLATE_DIRS, $configs['templateDir']);
            unset($configs['templateDir']);
        }

        // if there are other options set
        if (count($configs) > 0) {
            $container->setParameter(self::TWIG_OPTIONS, $configs);
        }
    }

    public function addTemplateDirLoad(array $configs, ContainerBuilder $container){
        ContainerUtil::addValueToArrayParameter($container, self::TWIG_TEMPLATE_DIRS, $configs['path']);
    }

    /**
     * Returns the base path for the XSD files.
     *
     * @return string The XSD base path
     */
    public function getXsdValidationBasePath() {
        return __DIR__ . '/resources/schema';
    }

    public function getNamespace() {
        return 'http://www.mitchellsoftware.net/schema/dic/twig';
    }

    public function getAlias() {
        return 'twig';
    }

}
